package com.simple.json;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;

import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

/**
 * 负责打印Java对象和Json的不同
 * 
 * @author dell
 * 
 */
public class DiffGenerator {

	private static final char NEXT_LINE = '\n';
	private static final String TAB = "    ";// 由于'\t'在logcat中打印不出来。。
	private Class<?> clazz;
	private JSONObject jsonObject;

	private HashMap<String, Integer> diffMaps = new HashMap<String, Integer>();

	private final int Flag_inNone = 0x0;
	private final int Flag_inClass = 0x1;
	private final int Flag_inJson = 0x2;

	public DiffGenerator(Class<?> clazz, JSONObject jsonObject) {
		this.clazz = clazz;
		this.jsonObject = jsonObject;
	}

	/**
	 * 将Java的成员变量添加进来
	 * 
	 * @param field
	 */
	public void addInClass(Field field) {
		String name = field.getName();
		Integer value = diffMaps.get(name);
		if (value == null) {
			value = Integer.valueOf(Flag_inNone);
		}
		// 自动装箱/拆箱
		value = value | Flag_inClass;
		diffMaps.put(name, value);
	}

	private void addInJson() {
		// 这里获取Json里面的key的值
		Iterator<String> jsonKeys = jsonObject.keys();
		while (jsonKeys.hasNext()) {
			String name = jsonKeys.next();
			Integer value = diffMaps.get(name);
			if (value == null) {
				value = Integer.valueOf(Flag_inNone);
			}
			// 自动装箱/拆箱
			value = value | Flag_inJson;
			diffMaps.put(name, value);
		}
	}

	/**
	 * 打印出不同
	 */
	public void logDiff() {
		try {
			addInJson();
			logHead();
			logBody();
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}

	private void logHead() {
		StringBuilder headBuilder = new StringBuilder();
		headBuilder.append("Key").append(TAB).append(clazz.getSimpleName())
				.append(TAB).append("Json").append(TAB).append("value")
				.append(NEXT_LINE);
		Log.v(Util.TAG, headBuilder.toString());
	}

	private void logBody() throws JSONException {
		for (String mapKey : diffMaps.keySet()) {
			boolean inClass = (diffMaps.get(mapKey).intValue() & Flag_inClass) == Flag_inClass;
			String inClassStr = inClass ? "√" : "×";
			boolean inJson = (diffMaps.get(mapKey).intValue() & Flag_inJson) == Flag_inJson;
			String inJsonStr = inJson ? "√" : "×";
			String value = inJson ? jsonObject.get(mapKey).toString()
					: "(Json Havn't)";
			if (value.length() > 15) {
				value = value.substring(0, 15) + "...";
			}

			StringBuilder resultBuilder = new StringBuilder();
			resultBuilder.append(mapKey).append(TAB).append(inClassStr)
					.append(TAB).append(inJsonStr).append(TAB).append(value)
					.append(NEXT_LINE);
			if (inClass && inJson) {
				Log.i(Util.TAG, resultBuilder.toString());
			} else {
				Log.w(Util.TAG, resultBuilder.toString());
			}
		}
	}

}
